package cn.izeno.wx.core

import cn.izeno.retrofit2.converter.string.StringConverterFactory
import cn.izeno.wx.annotations.XmlRes
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Converter
import retrofit2.Retrofit
import retrofit2.converter.fastjson.FastJsonConverterFactory
import retrofit2.converter.simplexml.SimpleXmlConverterFactory
import java.lang.reflect.Type

class MultiConverterFactory(
    val xml: SimpleXmlConverterFactory,
    val json: FastJsonConverterFactory,
    val string: StringConverterFactory = StringConverterFactory.create()
) : Converter.Factory() {

  override fun requestBodyConverter(type: Type, parameterAnnotations: Array<Annotation>, methodAnnotations: Array<Annotation>, retrofit: Retrofit): Converter<*, RequestBody>? {
    return when {
      type == String::class.java -> string.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit)
      methodAnnotations.find { it.annotationClass == XmlRes::class } != null -> {
        xml.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit)
      }
      else -> json.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit)
    }
  }

  override fun responseBodyConverter(type: Type, annotations: Array<Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? {
    return when {
      type == String::class.java -> string.responseBodyConverter(type, annotations, retrofit)
      annotations.find { it.annotationClass == XmlRes::class } != null -> {
        xml.responseBodyConverter(type, annotations, retrofit)
      }
      else -> json.responseBodyConverter(type, annotations, retrofit)
    }
  }

  companion object {
    fun create(xml: SimpleXmlConverterFactory = SimpleXmlConverterFactory.create(),
               json: FastJsonConverterFactory = FastJsonConverterFactory.create()
    ): MultiConverterFactory {
      return MultiConverterFactory(xml, json)
    }
  }

}